package com.yao.mybatis.config;

import com.yao.mybatis.utils.DocumentUtils;
import com.yao.mybatis.utils.Resources;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

/**
 * 解析全局配置文件
 *
 * @author Administrator
 */
public class XMLConfigParser {

    private static final Logger LOGGER = LogManager.getLogger("mylog");
    private Configuration configuration;

    public XMLConfigParser() {
        this.configuration = new Configuration();
    }

    public Configuration parse(InputStream inputStream) {
        Document document = DocumentUtils.readFileAsDocument(inputStream);
        //<configuration>
        assert document != null;
        Element rootElement = document.getRootElement();
        LOGGER.info("初始化configuration");
        parseEnvironments(rootElement);
        parseMappers(rootElement);
        return configuration;
    }

    /**
     * 解析全局配置文件的</environments>
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    private void parseEnvironments(@org.jetbrains.annotations.NotNull Element element) {
        LOGGER.info("开始解析环境配置");
        String defaultDev = element.element("environments").attribute("default").getValue();
        List<Element> elements = element.element("environments").elements("environment");
        DataSource ds = null;
        for (Element e : elements) {
            String id = e.attributeValue("id");
            if (!defaultDev.equals(id)) {
                continue;
            }
            LOGGER.info("start parse environment " + id);
            parseEnvironment(e);
            break;
        }
    }

    /**
     * 解析</environment>
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    private void parseEnvironment(Element element) {
        //解析数据库连接信息
        Element dataSource = element.element("dataSource");
        String type = dataSource.attributeValue("type");
        List<Element> properties = dataSource.elements("property");
        Properties pro = new Properties();
        for (Element e : properties) {
            pro.put(e.attributeValue("name"), e.attributeValue("value"));
        }
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName(pro.getProperty("driver"));
        ds.setUrl(pro.getProperty("url"));
        ds.setUsername(pro.getProperty("username"));
        ds.setPassword(pro.getProperty("password"));
        LOGGER.info("parse mysql config success " + properties.toString());
        configuration.setDataSource(ds);
    }

    /**
     * 解析<mappers>
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    private void parseMappers(Element element) {
        List<Element> elements = element.element("mappers").elements("mapper");
        XMLMapperParser xmlMapperParser = new XMLMapperParser(configuration);
        for (Element e : elements) {
            String resource = e.attributeValue("resource");
            LOGGER.info("start parse mapper file " + resource);
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            xmlMapperParser.parse(resourceAsStream);
        }
    }
}
